package com.xr.file.controller;

import com.xr.common.annotation.SystemLog;
import com.xr.common.axios.AxiosEnum;
import com.xr.common.axios.AxiosResult;
import com.xr.common.enums.LogType;
import com.xr.file.model.dto.FileDto;
import com.xr.file.model.dto.Result;
import com.xr.file.model.dto.TaskInfoDto;
import com.xr.file.model.entity.SysUploadTask;
import com.xr.file.model.param.InitTaskParam;
import com.xr.file.service.IFileService;
import com.xr.file.service.SysUploadTaskService;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 分片上传-分片任务记录(SysUploadTask)表控制层
 */
@RestController
@RequestMapping("/api/v1/file")
public class MinioUploadTaskController {

	/**
	 * 服务对象
	 */
	@Resource
	private SysUploadTaskService sysUploadTaskService;

	@Resource
	private IFileService iFileService;

	/**
	 * 获取上传进度
	 * @param identifier 文件md5
	 * @return
	 */
	@GetMapping("/tasks/{identifier}")
	public Result<TaskInfoDto> taskInfo(@PathVariable("identifier") String identifier) {
		return Result.ok(sysUploadTaskService.getTaskInfo(identifier));
	}

	/**
	 * 创建一个上传任务
	 * @return
	 */
	@SystemLog(module = "文件模块", type = LogType.UPLOAD, description = "分片上传文件")
	@PostMapping("/tasks")
	public Result initTask(@Valid @RequestBody InitTaskParam param, BindingResult bindingResult) {
		if (bindingResult.hasErrors()) {
			return Result.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
		}
		return Result.ok(sysUploadTaskService.initTask(param));
	}

	/**
	 * 获取每个分片的预签名上传地址
	 * @param identifier
	 * @param partNumber
	 * @return
	 */
	@GetMapping("/tasks/{identifier}/{partNumber}")
	public Result preSignUploadUrl(@PathVariable("identifier") String identifier,
			@PathVariable("partNumber") Integer partNumber) {
		SysUploadTask task = sysUploadTaskService.getByIdentifier(identifier);
		if (task == null) {
			return Result.error("分片任务不存在");
		}
		Map<String, String> params = new HashMap<>();
		params.put("partNumber", partNumber.toString());
		params.put("uploadId", task.getUploadId());
		return Result.ok(sysUploadTaskService.genPreSignUploadUrl(task.getBucketName(), task.getObjectKey(), params));
	}

	/**
	 * 合并分片
	 * @param identifier
	 * @return
	 */
	@PostMapping("/tasks/merge/{identifier}")
	public Result merge(@PathVariable("identifier") String identifier) {
		sysUploadTaskService.merge(identifier);
		return Result.ok();
	}

	/**
	 * 根据条件查询列表
	 * @param fileDto
	 * @return
	 */
	@ApiOperation(tags = "查询", value = "查询File信息")
	@GetMapping("/selectList")
	public AxiosResult selectList(FileDto fileDto) {
		return iFileService.selectList(fileDto);
	}

	/**
	 * 根据条件分页查询
	 * @param currentPage
	 * @param pageSize
	 * @param fileDto
	 * @return
	 */
	@ApiOperation(tags = "查询", value = "分页查询File信息")
	@GetMapping("/selectPage/{currentPage}/{pageSize}")
	public AxiosResult selectPage(@PathVariable int currentPage, @PathVariable int pageSize, FileDto fileDto) {
		return iFileService.selectPage(currentPage, pageSize, fileDto);
	}

	/**
	 * 根据id查询单个
	 * @param id
	 * @return
	 */
	@ApiOperation(tags = "查询", value = "根据id查询File信息")
	@GetMapping("/selectOneById/{id}")
	public AxiosResult selectOneById(@PathVariable Long id) {
		return iFileService.selectOneById(id);
	}

	/**
	 * 新增
	 * @param fileDto
	 * @return
	 */
	@ApiOperation(tags = "新增", value = "新增File信息")
	@PostMapping("/insert")
	public AxiosResult insert(@RequestBody FileDto fileDto) {
		return iFileService.insert(fileDto);
	}

	/**
	 * 更新
	 * @param fileDto
	 * @return
	 */
	@ApiOperation(tags = "更新", value = "更新File信息")
	@PutMapping("/update")
	public AxiosResult update(@RequestBody FileDto fileDto) {
		return iFileService.update(fileDto);
	}

	/**
	 * 根据id删除单个
	 * @param id
	 * @return
	 */
	@SystemLog(module = "文件模块", type = LogType.DELETE, description = "删除文件")
	@ApiOperation(tags = "删除", value = "删除File信息")
	@DeleteMapping("/delete/{id}")
	public AxiosResult delete(@PathVariable Long id) {
		return iFileService.delete(id);
	}

	/**
	 * 根据id集合批量删除
	 * @param idList
	 * @return
	 */
	@SystemLog(module = "文件模块", type = LogType.DELETE, description = "批量删除文件")
	@ApiOperation(tags = "删除", value = "批量删除File信息")
	@PostMapping("/deleteBatch")
	public AxiosResult deleteBatch(@RequestBody List<Long> idList) {
		return iFileService.deleteBatch(idList);
	}

	/**
	 * 导入文件
	 * @param file
	 * @return
	 */
	@SystemLog(module = "文件模块", type = LogType.IMPORT, description = "导入文件信息")
	@ApiOperation(tags = "导入", value = "导入File信息")
	@PostMapping("/importFile")
	public AxiosResult importFile(@RequestBody MultipartFile file) {
		return iFileService.importFile(file);
	}

	/**
	 * 导出文件
	 * @param response
	 */
	@SystemLog(module = "文件模块", type = LogType.EXPORT, description = "导出文件信息")
	@ApiOperation(tags = "导出", value = "导出File信息")
	@GetMapping("/exportFile")
	public AxiosResult exportFile(HttpServletResponse response) {
		iFileService.exportFile(response);
		return AxiosResult.success(AxiosEnum.EXPORT_SUCCESS);
	}

	/**
	 * 下载文件到本地
	 * @param url
	 * @param response
	 */
	@SystemLog(module = "文件模块", type = LogType.DOWNLOAD, description = "下载文件到本地")
	@ApiOperation(tags = "下载", value = "下载文件到本地")
	@GetMapping("/downloadFile")
	public AxiosResult downloadFile(String url, HttpServletResponse response) {
		iFileService.downloadFile(url, response);
		return AxiosResult.success(AxiosEnum.DOWNLOAD_SUCCESS);
	}

}
